﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics.Metrics;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CTC;
using static System.Windows.Forms.AxHost;

namespace CTCTest
{
    public partial class SlaveForm : Form
    {
        private CTCSlave Slave = null;
        private UInt32 MasterProductID = 0;
        private byte[] MasterDeviceID = new byte[16];
        private UInt16 MasterVersion = 0;
        private UInt32 SlaveProductID = 1;
        private byte[] SlaveDeviceID = new byte[16] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        /// <summary>
        /// 卡头投的币
        /// </summary>
        private UInt32 MasterCoinIn = 0;
        /// <summary>
        /// 游戏机投的币
        /// </summary>
        private UInt32 SlaveCoinIn = 0;
        public SlaveForm()
        {
            InitializeComponent();
            InstEnadle(false);
        }

        private void InstEnadle(bool ok)
        {
            btn_Atmosphere.Enabled = ok;
            btn_CoinIn.Enabled = ok;
            btn_Ticket.Enabled = ok;
            btn_ChangeState.Enabled = ok;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 定义一个字符串数组，并将获取到的电脑上串口名字赋值给它
            string[] ports = SerialPort.GetPortNames();

            // 遍历并打印所有找到的串口
            foreach (var port in ports)
            {
                comboBox_Serial.Items.Add(port);
            }
            //if (comboBox_Serial.Items.Count > 0)
            //{
            //    comboBox_Serial.SelectedIndex = 2;
            //}
            lab_SlaveProductID.Text = String.Format("SlaveProductID:{0}", SlaveProductID);
            lab_SlaveDeviceID.Text = String.Format("SlaveDeviceID:{0}", CRC.ToHexStringTrim(SlaveDeviceID));

        }
        private void btn_open_Click(object sender, EventArgs e)
        {
            if (comboBox_Serial.Items.Count == 0)
            {
                MessageBox.Show("没有可用串口", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (comboBox_Serial.SelectedIndex == -1)
            {
                MessageBox.Show("请选择要打开的串口", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            btn_open.Enabled = false;
            Slave = new CTCSlave(1, comboBox_Serial.SelectedItem.ToString(), SlaveProductID, SlaveDeviceID);
            Slave.DebugLogI += LogI;
            Slave.DebugLogE += LogE;
            Slave.OnHandshake += Slave_OnHandshake;
            Slave.OnStateChange += Slave_OnStateChange;
            Slave.OnCoinIn += Slave_OnCoinIn;
            Slave.OnMeterRead += Slave_OnMeterRead;
            Slave.OnQueryCoin += Slave_OnQueryCoin;
            Slave.OnSetCoinPrice += Slave_OnSetCoinPrice;
            Slave.OnSelectChannel += Slave_OnSelectChannel;
            Slave.OnSendFail += Slave_OnSendFail;
            Slave.OnMasterStateChange += Slave_OnMasterStateChange;
            Slave.Open();
        }

        private void Slave_OnMasterStateChange(byte player, byte[] data)
        {
            LogI(player, String.Format("Master状态变更  {0}", data[0]));
        }

        /// <summary>
        /// 发送数据失败回调
        /// </summary>
        /// <param name="state">失败状态  CTC_CMD_ACK</param>
        /// <param name="player">P位</param>
        /// <param name="inst">指令</param>
        /// <param name="data">数据</param>
        private void Slave_OnSendFail(byte state, byte player, byte[] inst, byte[] data)
        {
            LogI(player, String.Format("数据发送失败:{0}", CRC.ToHexStringTrim(inst)));
        }

        private void Slave_OnSelectChannel(byte player, byte[] data)
        {
            /**
             * 彩票通道	1字节	0=实物,1=电子,2=暂时不出
             * 蓝票通道	1字节	0=实物,1=电子,2=暂时不出
             */
            LogI(player, String.Format("通道选择:{0}", CRC.ToHexString(data)));
        }


        private void Slave_OnSetCoinPrice(byte player, byte[] data)
        {
            /**
             * 每局币数	2字节	每局游戏需要的投币数(投币器的脉冲数)
             */
            UInt16 num = CRC.BytesToUint16(data);
            LogI(player, String.Format("设置每局币数:{0}", num));
        }

        private void Slave_OnQueryCoin(byte player)
        {
            Slave.RspQueryCoin(55);
        }

        private void Slave_OnMeterRead(byte player)
        {
            /**
             * 5个byte为一组,一共10组50个byte
             * 0:类型
             * 1-4:数据
             * 
             * 类型
             * 0=投币总数,1=电子币总数,2=实物币总数
             * 10=出票总数,11=出电子票总数,12=出实物票总数
             * 20=出蓝票总数,21=出电子蓝票总数,22=出实物蓝票总数
             * 30=总出卡片数
             * 100=出礼品1总数,101=出实物礼品2总数,102=出实物礼品2总数,103=出实物礼品4总数,104=出实物礼品5总数,...130=出实物礼品31总数
             * 255=数据结束(无效后面不能再放有效数据)
             */
            byte[] data = new byte[50];
            data[0] = 0;
            Array.Copy(CRC.Uint32ToBytes(10), 0, data, 1, 4);
            Slave.RspMeterRead(data);
        }

        private void Slave_OnCoinIn(byte player, byte[] data)
        {
            /**
             * 投币数量	4字节	投币数量
             * 会员ID	16字节	同一张会员卡或同一个会员账户时ID相同
             * 消费记录ID	16字节	标识此笔交易的ID
             */
            UInt32 num = CRC.BytesToUint32(data[0], data[1], data[2], data[3]);
            MasterCoinIn += num;
            byte[] memberID = CRC.SubByteData(data, 4, 16);
            byte[] orderID = CRC.SubByteData(data, 20, 16);
            LogI(player, String.Format("收到卡头投币:{0}-{1}-{2}", num, CRC.ToHexStringTrim(memberID), CRC.ToHexStringTrim(orderID)));
            Slave.RspCoinIn(data[0], orderID);
            this.Invoke((MethodInvoker)delegate
            {
                lab_MasterCoinIn.Text = String.Format("MasterCoinIn:{0}", MasterCoinIn);
            });
        }

        private void Slave_OnStateChange(byte player, CTCClientConnState state)
        {
            this.Invoke((MethodInvoker)delegate
            {
                if (state == CTCClientConnState.Connected)
                {
                    lab_ConnState.ForeColor = Color.Green;
                    InstEnadle(true);
                }
                else
                {
                    lab_ConnState.ForeColor = Color.Red;
                    InstEnadle(false);
                }
                lab_ConnState.Text = state.ToString();
            });
        }

        private void Slave_OnHandshake(byte player, byte[] data)
        {
            /**
              * 产品ID	4字节	CTC官网分配的产品ID,用于查询是哪个厂家出的什么产品
              * 设备ID	16字节	每个设备自己保证全球唯一
              * 支持的CTC协议最高版本	2字节	本设备支持的CTC协议最高版本
              * */
            MasterProductID = CRC.BytesToUint32(data[0], data[1], data[2], data[3]);
            Array.Copy(data, 4, MasterDeviceID, 0, 16);
            MasterVersion = CRC.BytesToUint16(data[20], data[21]);
            LogI(player, String.Format("MasterVsion:{0}", MasterVersion));
            try
            {
                this.Invoke((MethodInvoker)delegate
                {
                    lab_MasterProductID.Text = String.Format("MasterProductID:{0}", MasterProductID);
                    lab_MasterDeviceID.Text = String.Format("MasterDeviceID:{0}", CRC.ToHexStringTrim(MasterDeviceID));
                });
            }
            catch { }
        }

        private void LogI(byte player, string msg)
        {
            try
            {
                this.Invoke((MethodInvoker)delegate
                {
                    richTextBox1.AppendText(msg + "\n");
                });
            }
            catch { }
        }
        private void LogE(byte player, string msg)
        {
            try
            {
                this.Invoke((MethodInvoker)delegate
                {
                    richTextBox1.AppendText(msg + "\n");
                });
            }
            catch { }

        }

        private void btn_Atmosphere_Click(object sender, EventArgs e)
        {
            Slave.SendAtmosphere(0, 0, 100);
        }

        private void MasterForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Slave != null)
            {
                Slave.Close();
            }
        }

        private void btn_CoinIn_Click(object sender, EventArgs e)
        {
            /**
            * 实物类型	1字节	0=实物币,1=实物彩票,2=实体蓝票,3=实体卡片,100=实物礼品1,101=实物礼品2...130=实物礼品31
            * 奖励数量	4字节	上报数量
            */
            Slave.SendPhysicalReport(0, 1);
        }

        private void btn_Ticket_Click(object sender, EventArgs e)
        {

            /**
          * 实物类型	1字节	0=奖励彩票,1=奖励蓝票,10=游戏任务得分
          * 奖励数量	奖励的数量
          */
            Slave.SendReward(0, 10);
        }

        private void btn_ChangeState_Click(object sender, EventArgs e)
        {
            if (Slave.SlaveState == 0)
            {
                Slave.ChangeState(1, 11);
            }
            else
            {
                Slave.ChangeState(0, 0);
            }
        }
    }
}
